package org.ws.httphelper.support.fetcher;

import com.google.common.collect.Maps;
import org.ws.httphelper.core.fetcher.HttpFetcher;
import org.ws.httphelper.model.config.ClientConfig;
import org.ws.httphelper.model.http.ClientType;

import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 抓取器池
 */
public class FetcherPool {

    /**
     * 单例
     */
    private static final FetcherPool INSTANCE = new FetcherPool();
    /**
     * 根据相同配置生成的key于HttpFetcher实例对应Map
     */
    private Map<String,HttpFetcher> fetcherMap = Maps.newConcurrentMap();
    /**
     * HttpFetcher计数索引：私有Client的key会使用
     */
    private AtomicInteger index = new AtomicInteger(0);

    private FetcherPool() { }

    /**
     * 获取FetcherPool
     * @return
     */
    public static FetcherPool getInstance() {
        return INSTANCE;
    }

    /**
     * 根据client配置获取HttpFetcher
     * @param clientConfig client配置
     * @return
     */
    public HttpFetcher getHttpFetcher(ClientConfig clientConfig){
        HttpFetcher fetcher;
        // 根据config获取key：所有字段拼接
        String key = getKey(clientConfig);
        // 私有Client使用创建新的
        if(clientConfig.isPrivateClient()){
            // 生成一个新的fetcher
            fetcher = newHttpFetcher(clientConfig);
            // map的key为config生成的key+index
            fetcherMap.put(key+index.get(), fetcher);
        }
        else {
            // 公有Client:相同配置使用一个对象
            if(!fetcherMap.containsKey(key)){
                // 该config下没有fetcher，生成一个新的
                fetcher = newHttpFetcher(clientConfig);
                fetcherMap.put(key, fetcher);
            }
            else {
                // 该config下已存在fetcher，则公用
                fetcher = fetcherMap.get(key);
            }
        }
        return fetcher;
    }

    /**
     * 根据config获取key。
     * 将所有字段拼接，相同的配置获取的key相同
     * @param clientConfig
     * @return
     */
    private String getKey(ClientConfig clientConfig){
        StringBuilder keyBuilder = new StringBuilder();
        keyBuilder.append(clientConfig.getThreadNumber())
                .append(clientConfig.getTimeout())
                .append(clientConfig.getClientType().name())
                .append(clientConfig.isEnableSsl()?"1":"0")
                .append(clientConfig.isFollowRedirects()?"1":"0")
                .append(clientConfig.isEnableCookie()?"1":"0");
        return keyBuilder.toString();
    }

    /**
     * 根据配置生成一个HttpFetcher
     * @param clientConfig
     * @return
     */
    private HttpFetcher newHttpFetcher(ClientConfig clientConfig){
        // index++
        index.incrementAndGet();
        // 客户端类型为WebClient
        if(clientConfig.getClientType() == ClientType.WEB_CLIENT) {
            return new WebClientFetcher(clientConfig);
        }
        else {
            // 客户端类型为OkHttpClient
            return new OkHttpClientFetcher(clientConfig);
        }
    }


}
